package com.auth.service.impl;

import cn.hutool.core.util.StrUtil;
import com.common.dto.LoginFormDTO;
import com.auth.domain.dto.RegisterFormDTO;
import com.auth.domain.dto.UpdateUserDTO;
import com.auth.domain.entity.User;
import com.auth.domain.entity.UserPermission;
import com.auth.domain.vo.UserInfoVO;
import com.auth.mapper.UserMapper;
import com.auth.service.IUserPermissionService;
import com.auth.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.utils.JwtUtil;
import com.common.utils.RequestContextUtil;
import com.common.vo.RegisterVO;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author 坤哥
 * @since 2025-10-08
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private IUserPermissionService userPermissionService;

    /**
     * 用户注册
     */
    @Override
    public RegisterVO register(RegisterFormDTO registerFormDTO) {
        //验证两次传来的密码是否一致
        if(!registerFormDTO.getPassword().equals(registerFormDTO.getConfirmPassword())){
            throw new RuntimeException("两次输入的密码不一致");
        }
        //验证用户名是否已被被人占用
        Long count = lambdaQuery().eq(User::getUserName, registerFormDTO.getUsername()).count();
        if(count > 0){
            throw new RuntimeException("用户名已被占用");
        }
        User user = User.builder()
                .userName(registerFormDTO.getUsername())
                .password(registerFormDTO.getPassword())
                .avatar("https://tlias-0626.oss-cn-hangzhou.aliyuncs.com/2025/06/86dff275-7fc9-45a5-b31a-2b97b96ddb39.png")
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        save(user);
        return new RegisterVO(user.getUserName(), user.getId());
    }
    /**
     * 用户登录
     */
    @Override
    public String login(LoginFormDTO loginFormDTO) {
        User user = lambdaQuery().eq(User::getUserName, loginFormDTO.getUsername()).one();
        if(user == null){
            throw new RuntimeException("用户不存在");
        }
        if(!Objects.equals(user.getPassword(), loginFormDTO.getPassword())){
            throw new RuntimeException("用户名或密码错误");
        }
        Long userId = user.getId();
        Map<String,Object> map = new HashMap<>();
        map.put("userId",userId);
        map.put("username",user.getUserName());
        String token = JwtUtil.createJwt(map);
        //把完整的用户信息存入redis，userId作为key
        stringRedisTemplate.opsForValue().set("login:token:" + userId,token,4, TimeUnit.HOURS);
        return token;
    }
    /**
     * 用户登出
     */
    @Override
    public void logout() {
        //把用户信息和token从redis中删除
        Long userId = RequestContextUtil.getCurrentUserId();
        stringRedisTemplate.delete("login:token:" + userId);
    }
    /**
     * 获取用户信息
     */
    @Override
    public UserInfoVO getUserInfo() {
        Long userId = RequestContextUtil.getCurrentUserId();
        User user = getById(userId);
        List<UserPermission> userPermissions = userPermissionService.lambdaQuery().eq(UserPermission::getUserId, userId).list();
        List<String> buttons = userPermissions.stream().map(UserPermission::getButton).toList();
        return new UserInfoVO(user.getUserName(),user.getAvatar(),buttons);
    }

    /**
     * 获取用户列表（分页）
     */
    @Override
    public IPage<User> getUserList(String username, Integer pageNum, Integer pageSize) {
        // 创建分页对象
        Page<User> page = new Page<>(pageNum, pageSize);
        
        // 构建查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(username), User::getUserName, username)
                   .eq(User::getDelFlag, 0) // 只查询未删除的用户
                   .orderByDesc(User::getCreateTime); // 按创建时间倒序
        
        // 分页查询
        return page(page, queryWrapper);
    }

    /**
     * 更新用户信息
     */
    @Override
    public void updateUser(UpdateUserDTO updateUserDTO) {
        // 检查用户是否存在
        User existUser = getById(updateUserDTO.getId());
        if (existUser == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 如果修改了用户名，检查用户名是否已被占用
        if (StrUtil.isNotBlank(updateUserDTO.getUserName()) 
            && !updateUserDTO.getUserName().equals(existUser.getUserName())) {
            Long count = lambdaQuery()
                .eq(User::getUserName, updateUserDTO.getUserName())
                .ne(User::getId, updateUserDTO.getId())
                .count();
            if (count > 0) {
                throw new RuntimeException("用户名已被占用");
            }
        }
        
        // 使用 LambdaUpdateWrapper 进行更新
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, updateUserDTO.getId())
                    .set(StrUtil.isNotBlank(updateUserDTO.getUserName()), User::getUserName, updateUserDTO.getUserName())
                    .set(StrUtil.isNotBlank(updateUserDTO.getAvatar()), User::getAvatar, updateUserDTO.getAvatar())
                    .set(StrUtil.isNotBlank(updateUserDTO.getSex()), User::getSex, updateUserDTO.getSex())
                    .set(StrUtil.isNotBlank(updateUserDTO.getStatus()), User::getStatus, updateUserDTO.getStatus())
                    .set(User::getUpdateTime, LocalDateTime.now());
        
        update(updateWrapper);
    }

    /**
     * 删除用户（软删除）
     */
    @Override
    public void deleteUser(Long id) {
        // 检查用户是否存在
        User user = getById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 软删除：设置 delFlag = 1
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, id)
                    .set(User::getDelFlag, 1)
                    .set(User::getUpdateTime, LocalDateTime.now());
        
        update(updateWrapper);
        
        // 删除 Redis 中的 token
        stringRedisTemplate.delete("login:token:" + id);
    }

    /**
     * openFeign根据用户名获取用户id
     */
    @Override
    public Long getByUsername(String username) {
        User user = lambdaQuery().eq(User::getUserName, username).one();
        if(user == null){
            throw new RuntimeException("用户不存在");
        }
        return user.getId();
    }

    /**
     * openFeign根据用户id获取用户名
     */
    @Override
    public String getByUserId(Long userId) {
        User user = getById(userId);
        return user.getUserName();
    }
}
